package com.pdool.room.fight;

import cn.hutool.core.util.RandomUtil;
import com.pdool.common.constants.Constant;
import com.pdool.common.dict.CardEffectVo;
import com.pdool.room.context.RoleFightInfo;
import com.pdool.room.context.RoomContext;
import com.pdool.room.enums.CampTypeEnum;
import com.pdool.room.fight.area.FightAreaInfo;
import com.pdool.room.fight.area.HandAreaInfo;
import com.pdool.room.fight.effect.CardFightVo;
import com.pdool.room.fight.effect.EffectFightVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Consumer;

@Component
@Slf4j
public class TargetSelectUtil {
    static TargetSelectUtil instance;

    public TargetSelectUtil() {
        instance = this;
    }

    public static TargetSelectUtil getInstance() {
        return instance;
    }

    public List<Object> targetSelect(RoomContext roomContext, EffectFightVo effectFightVo) {
        List<Object> resultList = new ArrayList<>();
        CardEffectVo effectConfigVo = effectFightVo.getEffectConfigVo();
        String[] targetCondition = effectConfigVo.getTargetCondition();
        int type = Integer.parseInt(targetCondition[0]);

        switch (type) {
            case Constant.TARGET_DETAIL_TYPE_1://卡牌 筛出来时卡牌列表List<CardFightVo>
                targetSelect1(roomContext, effectFightVo, resultList);
                break;
            case Constant.TARGET_DETAIL_TYPE_2://   区域 筛出来是区域信息List<AreaInfo>
                targetSelect2(roomContext, effectFightVo, resultList);
                break;
            case Constant.TARGET_DETAIL_TYPE_3://   玩家数据 筛出来是区域信息List<RoleFightInfo>
                targetSelect3(roomContext, effectFightVo, resultList);
                break;
            case Constant.TARGET_DETAIL_TYPE_4://   无目标，不做逻辑
                break;
        }

        return resultList;
    }

    private void targetSelect3(RoomContext roomContext, EffectFightVo effectFightVo, List<Object> resultList) {
        int campType = effectFightVo.getEffectConfigVo().getCampType();
        int pos = effectFightVo.getCardFightVo().getPos();
        if (campType == CampTypeEnum.SELF.getType()) {
            RoleFightInfo roleFightInfo = roomContext.getMemberMap().get(effectFightVo.getCardFightVo().getRoleId());
            resultList.add(roleFightInfo);
        } else if (campType == CampTypeEnum.ENEMY.getType()) {
            for (RoleFightInfo value : roomContext.getMemberMap().values()) {
                //  阵营不同就是敌人
                if (value.getPos() != pos) {
                    resultList.add(value);
                }
            }
        } else {
            resultList.addAll(roomContext.getMemberMap().values());
        }
    }

    private void targetSelect2(RoomContext roomContext, EffectFightVo effectFightVo, List<Object> resultList) {
        int areaType = effectFightVo.getEffectConfigVo().getAreaType();
        if (areaType == Constant.AREA_TYPE_6 || areaType == Constant.AREA_TYPE_7) {
            List<HandAreaInfo> handArea = getHandArea(roomContext, effectFightVo);
            resultList.addAll(handArea);
        }
        if (areaType != Constant.AREA_TYPE_6) {
            List<FightAreaInfo> areaObject = getFightAreaObject(roomContext, effectFightVo);
            resultList.addAll(areaObject);
        }
    }

    private List<HandAreaInfo> getHandArea(RoomContext roomContext, EffectFightVo effectFightVo) {
        int campType = effectFightVo.getEffectConfigVo().getCampType();
        List<HandAreaInfo> resultList = new ArrayList<>();
        if (CampTypeEnum.SELF.getType() == campType) {
            RoleFightInfo roleFightInfo = roomContext.getMemberMap().get(effectFightVo.getCardFightVo().getRoleId());
            resultList.add(roleFightInfo.getHandAreaInfo());
        } else if (CampTypeEnum.ENEMY.getType() == campType) {
            for (RoleFightInfo value : roomContext.getMemberMap().values()) {
                //  阵营不同就是敌人
                if (value.getPos() != effectFightVo.getCardFightVo().getPos()) {
                    resultList.add(value.getHandAreaInfo());
                }
            }
        } else {
            for (RoleFightInfo value : roomContext.getMemberMap().values()) {
                resultList.add(value.getHandAreaInfo());
            }
        }
        return resultList;
    }

    //      T 类型(负数，排除此类型) E能量区间 N牌的数量
    //      1卡牌（前面已经筛选出卡牌（包括手牌））
    //      1_T_E1_E2_N
    private void targetSelect1(RoomContext roomContext, EffectFightVo effectFightVo, List<Object> resultList) {
        CardEffectVo effectConfigVo = effectFightVo.getEffectConfigVo();
        int areaType = effectConfigVo.getAreaType();
        String[] targetCondition = effectConfigVo.getTargetCondition();

        List<CardFightVo> selectCardList = new ArrayList<>();
        //  手牌
        if (areaType == Constant.AREA_TYPE_6) {
            selectCardList = getHandCard(effectFightVo, roomContext);
        } else {
            List<FightAreaInfo> areaObject = getFightAreaObject(roomContext, effectFightVo);
            for (FightAreaInfo areaInfo : areaObject) {
                List<CardFightVo> cardList = areaInfo.getCardList();
                selectCardList.addAll(cardList);
            }
        }

        checkCardType(selectCardList, targetCondition);
        checkEnergy(selectCardList, targetCondition);
        checkNum(selectCardList, targetCondition);

        resultList.addAll(selectCardList);
    }

    private void checkNum(List<CardFightVo> selectCardList, String[] targetCondition) {
        if (targetCondition.length < 5) {
            return;
        }
        int num = Integer.parseInt(targetCondition[4]);
        int select = Math.min(selectCardList.size() , num);
        Set<CardFightVo> cardFightVos = RandomUtil.randomEleSet(selectCardList, select);
        selectCardList.clear();
        selectCardList.addAll(cardFightVos);
    }

    public static void main(String[] args) {
        List<Integer> selectCardList = new ArrayList<>();
//        selectCardList.add(9);
//        selectCardList.add(8);
//        selectCardList.add(7);
        int select = Math.min(selectCardList.size() , 999);
        Set<Integer> integers = RandomUtil.randomEleSet(selectCardList, select);
        System.out.println();
    }
    private void checkEnergy(List<CardFightVo> selectCardList, String[] targetCondition) {
        if (targetCondition.length <= 4) {
            return;
        }
        int minE = Integer.parseInt(targetCondition[2]);
        int maxE = Integer.parseInt(targetCondition[3]);

        Iterator<CardFightVo> iterator = selectCardList.iterator();
        while (iterator.hasNext()) {
            CardFightVo next = iterator.next();
            int cost = next.getCost();
            if (cost < minE || cost > maxE) {
                iterator.remove();
            }
        }
    }

    private void checkCardType(List<CardFightVo> selectCardList, String[] targetCondition) {
        if (targetCondition.length < 2) {
            return;
        }
        //  类型可能是公式 2&4  99 表示全部
        String s = targetCondition[1];
        if ("99".equals(s)) {
            return;
        }
        String[] split = s.split(Constant.SPLIT_AND);
        Set<Integer> needSet = new HashSet<>();
        for (String s1 : split) {
            needSet.add(Integer.valueOf(s1));
        }
        selectCardList.removeIf(next -> !needSet.contains(next.getCardType()));
    }

    //  筛选手牌
    private List<CardFightVo> getHandCard(EffectFightVo effectFightVo, RoomContext roomContext) {
        int campType = effectFightVo.getEffectConfigVo().getCampType();
        List<CardFightVo> resultList = new ArrayList<>();
        if (campType == CampTypeEnum.ALL.getType()) {
            for (RoleFightInfo value : roomContext.getMemberMap().values()) {
                //  阵营不同就是敌人
                List<CardFightVo> cardList = value.getHandAreaInfo().getCardList();
                resultList.addAll(cardList);
            }
        } else {
            long roleId = effectFightVo.getCardFightVo().getRoleId();
            int pos = effectFightVo.getCardFightVo().getPos();
            if (campType == CampTypeEnum.SELF.getType()) {
                RoleFightInfo roleFightInfo = roomContext.getMemberMap().get(roleId);
                List<CardFightVo> cardList = roleFightInfo.getHandAreaInfo().getCardList();
                resultList.addAll(cardList);
            } else if (campType == CampTypeEnum.ENEMY.getType()) {

                for (RoleFightInfo value : roomContext.getMemberMap().values()) {
                    //  阵营不同就是敌人
                    if (value.getPos() != pos) {
                        List<CardFightVo> cardList = value.getHandAreaInfo().getCardList();
                        resultList.addAll(cardList);
                    }
                }
            }
        }
        return resultList;
    }

    private List<FightAreaInfo> getFightAreaObject(RoomContext roomContext, EffectFightVo effectFightVo) {
        CardEffectVo effectConfigVo = effectFightVo.getEffectConfigVo();
        int campType = effectConfigVo.getCampType();
        int areaType = effectConfigVo.getAreaType();
        int areaId = effectFightVo.getAreaId();
        List<FightAreaInfo> resultList = new ArrayList<>();

        if (campType == CampTypeEnum.ALL.getType()) {
            for (RoleFightInfo value : roomContext.getMemberMap().values()) {
                for (FightAreaInfo areaInfo : value.getAreaInfoList()) {
                    if (checkArea(areaId, areaType, areaInfo)) {
                        resultList.add(areaInfo);
                    }
                }
            }
        } else {

            long self = effectFightVo.getCardFightVo().getRoleId();
            RoleFightInfo roleFightInfo = roomContext.getMemberMap().get(self);

            Consumer<RoleFightInfo> consumer3 = (v) -> {
                for (FightAreaInfo areaInfo : v.getAreaInfoList()) {
                    if (checkArea(areaId, areaType, areaInfo)) {
                        resultList.add(areaInfo);
                    }
                }
            };

            if (campType == CampTypeEnum.ENEMY.getType()) {
                for (RoleFightInfo value : roomContext.getMemberMap().values()) {
                    //  阵营不同就是敌人
                    if (value.getPos() != roleFightInfo.getPos()) {
                        consumer3.accept(value);
                    }
                }
            } else {

                consumer3.accept(roleFightInfo);
            }

        }
        return resultList;
    }

    // 检查区域是否符合（除手牌区域外）
    public boolean checkArea(int areaId, int areaType, FightAreaInfo areaInfo) {
        switch (areaType) {
            case Constant.AREA_TYPE_0://    当前
                return areaInfo.getAreaId() == areaId;
            case Constant.AREA_TYPE_1:// 相邻
                return (areaInfo.getAreaId() == areaId + 1) || (areaInfo.getAreaId() == areaId - 1);
            case Constant.AREA_TYPE_2:// 左侧
                return areaInfo.getAreaId() == areaId - 1;
            case Constant.AREA_TYPE_3:// 右侧
                return areaInfo.getAreaId() == areaId + 1;
            case Constant.AREA_TYPE_4:// 全部区域（不包括手牌）
                return true;
            case Constant.AREA_TYPE_5:// 除当前之外的所有区域
                return areaInfo.getAreaId() != areaId;
            case Constant.AREA_TYPE_7:// 手牌区域+ 战场区域（全部卡牌）
                return true;
            default:
                return true;
        }
    }
}
